package com.pocket.demo.core.mq.rabbitMQ;

import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.retry.MessageRecoverer;
import org.springframework.amqp.rabbit.retry.RepublishMessageRecoverer;
import org.springframework.context.annotation.Bean;

/**
 * @author cookie. 【demo-MQ-rabbitMQ-6.7】
 **/
//@Configuration
//@ConditionalOnProperty(name = "spring.rabbitmq.listener.simple.retry.enabled", havingValue = "true")
public class ErrorMessageConfig {

    public static final String ERROR_EXCHANGE = "pocket.error.direct";
    public static final String ERROR_QUEUE = "pocket.error.queue";
    public static final String ERROR_ROUTING_KEY = "error";

    @Bean
    public DirectExchange errorMessageExchange(){
        return new DirectExchange(ERROR_EXCHANGE, true, false);
    }
    @Bean
    public Queue errorQueue(){
        return new Queue(ERROR_QUEUE, true, true, false);
    }
    @Bean
    public Binding errorBinding(Queue errorQueue, DirectExchange errorMessageExchange){
        return BindingBuilder.bind(errorQueue).to(errorMessageExchange).with(ERROR_ROUTING_KEY);
    }

    /**
     * 定义消息消费失败处理策略。在消费消息失败 且 达到最大重试次数后，spring 提供了三种处理策略：
     * 1. RejectAndDontRequeueRecoverer：重试耗尽后，直接reject，丢弃消息;（默认）
     * 2. ImmediateRequeueMessageRecoverer：重试耗尽后，返回nack，消息重新入队，再次发送;
     * 3. RepublishMessageRecoverer：重试耗尽后，将失败消息投递到 指定交换机和队列中。（建议）
     * @param rabbitTemplate
     * @return
     */
    @Bean
    public MessageRecoverer republishMessageRecoverer(RabbitTemplate rabbitTemplate){
        return new RepublishMessageRecoverer(rabbitTemplate, ERROR_EXCHANGE, ERROR_ROUTING_KEY);
    }
}
